package com.sinosoft.vaccinetoai.utils.jwt;

import com.sinosoft.vaccinetoai.exception.BusinessException;
import com.sinosoft.vaccinetoai.exception.ExceptionEnums;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;

import java.security.KeyFactory;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Date;

@Slf4j
public class JwtValidator {

    // 缓存公钥
    private static RSAPublicKey cachedPublicKey;

    // 静态块：应用启动时加载公钥并缓存
    static {
        try {
            loadPublicKey();
        } catch (Exception e) {
            log.error("Error loading public key: {}", e.getMessage());
        }
    }

    // 加载并缓存公钥
    private static void loadPublicKey() throws Exception {
        // 读取公钥文件 (在 resources/certificates 目录下的 public_key.pem)
        String publicKeyPEM = new String("-----BEGIN PUBLIC KEY-----\n" +
                "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3cBw2bF9gnAMglgtVZ2T\n" +
                "lUvWluqCJj9Ryqp8COc0JMfTFCDR26KYs1o+jIcdOAxhR/5B2W1vUzHG0ODfLFHY\n" +
                "5uLxiBqo+ps67ON6IgB3pTqFjbuz0nLrBNQAiZV2LnPp/onQ68FYuQ87+Mw6mS6r\n" +
                "7xoilokKoFhGDXdg/JU6/gwrvZHRb6TYbIah4+SbMvxrDBI6RlCADOI6zQk+vb6C\n" +
                "gjmqGK/B/IAcU5E8JInNRcq3PGtxD91qJhU17PAssL7o0ZaIY/ffeTneJJ2gnBuR\n" +
                "5Z7KD1blJROst5rMywpEo/OS9R1pOXeil8Dk74GtV9kLDmcRtKvGMIm6nRFChA5z\n" +
                "9wIDAQAB\n" +
                "-----END PUBLIC KEY-----");

        // 去掉 PEM 格式的头尾部分
        publicKeyPEM = publicKeyPEM.replace("-----BEGIN PUBLIC KEY-----", "")
                .replace("-----END PUBLIC KEY-----", "").replaceAll("\\s+", "");

        // 解码 Base64 字符串
        byte[] decoded = Base64.getDecoder().decode(publicKeyPEM);

        // 使用 KeyFactory 创建公钥对象
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decoded);
        cachedPublicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);

        log.info("Public key loaded and cached successfully.");
    }

    public static void validateToken(String jwt) {
        try {
            if (jwt == null || jwt.isEmpty()) {
                log.error("JWT is missing.");
                throw BusinessException.ofExceptionEnums(ExceptionEnums.JWT_MISSING);
            }

            // 解析并验证JWT
            Jws<Claims> claims = Jwts.parserBuilder()
                    .setSigningKey(cachedPublicKey)
                    .build()
                    .parseClaimsJws(jwt);

            Claims body = claims.getBody();

            // 验证 JWT 是否过期
            Date expiration = body.getExpiration();
            if (expiration.before(new Date())) {
                log.warn("JWT expired.");
                throw BusinessException.ofExceptionEnums(ExceptionEnums.JWT_EXPIRED);
            }

            // 验证签发时间和过期时间是否超过 3 天
            Date issuedAt = body.getIssuedAt();
            long maxDurationMillis = 3 * 24 * 60 * 60 * 1000L; // 3天
            if (expiration.getTime() - issuedAt.getTime() > maxDurationMillis) {
                log.warn("JWT duration exceeds 3 days.");
                throw BusinessException.ofExceptionEnums(ExceptionEnums.JWT_DURATION_EXCEEDS_LIMIT);
            }

            // 验证签发者
//            String issuer = body.getIssuer();
//            if (!"expected-issuer".equals(issuer)) {
//                log.warn("Invalid issuer: {}", issuer);
//                throw BusinessException.ofExceptionEnums(ExceptionEnums.JWT_INVALID_ISSUER);
//            }
//
//            // 验证接收者
//            String audience = body.getAudience();
//            if (!"expected-audience".equals(audience)) {
//                log.warn("Invalid audience: {}", audience);
//                throw BusinessException.ofExceptionEnums(ExceptionEnums.JWT_INVALID_AUDIENCE);
//            }
            log.info("JWT is valid.");
        }
        catch (ExpiredJwtException e){
            log.error("JWT expired.");
            throw BusinessException.ofExceptionEnums(ExceptionEnums.JWT_EXPIRED);
        }
        catch (JwtException e) {
            log.error("JWT signature verification failed: {}", e.getMessage());
            throw BusinessException.ofExceptionEnums(ExceptionEnums.JWT_SIGNATURE_VERIFICATION_FAILED,e.getMessage());
        } catch (IllegalArgumentException e) {
            log.error("JWT parsing failed: {}", e.getMessage());
            throw BusinessException.ofExceptionEnums(ExceptionEnums.JWT_PARSING_FAILED);
        }
    }

}
